package top.tenebrous.yzl.im.handler.channel;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;
import top.tenebrous.yzl.im.contants.CommonConstants;
import top.tenebrous.yzl.im.context.ImContext;
import top.tenebrous.yzl.im.enums.ChannelType;
import top.tenebrous.yzl.im.enums.ChatType;
import top.tenebrous.yzl.im.enums.MessageType;
import top.tenebrous.yzl.im.factory.channel.ChannelFactory;
import top.tenebrous.yzl.im.factory.message.MessageFactory;
import top.tenebrous.yzl.im.handler.MessageHandler;
import top.tenebrous.yzl.im.interceptor.ImWebsocketInterceptor;
import top.tenebrous.yzl.im.message.Message;
import top.tenebrous.yzl.im.message.MessageBody;
import top.tenebrous.yzl.im.utils.WebSocketUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author yazhang6
 */
@Slf4j
@Component
public class MessageChannel implements Channel<MessageBody>, InitializingBean {

    @Autowired
    private ChannelFactory<MessageBody> channelFactory;

    @Autowired
    private MessageFactory messageFactory;

    @Autowired
    private ImContext imContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        channelFactory.register(ChannelType.SEND_CHANNEL, this);
    }


    @Override
    public void doHandler(WebSocketSession session, String type, MessageBody messageBody) {
        // 获取
        if (Objects.equals(messageBody.getChatType(), ChatType.PRIVATE_CHAT_TYPE.getCode())) {
            WebSocketSession toSession = WebSocketUtils.getSession(messageBody.getTo());
            if (Objects.isNull(toSession)) {
                log.warn("{} 服务端--->消息接收者[{}]不在线或不存在", CommonConstants.LOG_PREFIX,  messageBody.getTo());
            }
        }

        List<Map.Entry<ImWebsocketInterceptor, Integer>> sortList = imContext.handlerInterceptorSorted();

        log.info("{} 接收到来自:[{}]的消息, 消息内容:[{}]", CommonConstants.LOG_PREFIX, messageBody.getFrom(), JSON.toJSONString(messageBody));
        try {

            // 执行扩展拦截
            for (Map.Entry<ImWebsocketInterceptor, Integer> entry : sortList) {
                entry.getKey().beforeImWebSocketOnMessageProcessor(messageBody.getFrom(), messageBody);
            }

            MessageHandler<MessageBody> messageHandler = messageFactory.getInstance(MessageType.getMessageType(type));
            if (messageHandler == null) {
                log.warn("{} 无可用消息处理策略类，请确保依赖完整", CommonConstants.LOG_PREFIX);
                return;
            }
            messageHandler.execute(session, messageBody);
            // 后置消息处理
            for (Map.Entry<ImWebsocketInterceptor, Integer> entry : sortList) {
                entry.getKey().afterImWebSocketOnMessageProcessor(messageBody.getFrom(), messageBody);
            }
        } catch (Exception e) {
            log.error("{} 发送消息异常:{}", CommonConstants.LOG_PREFIX, e);
            e.printStackTrace();
        }
        log.info("{} 服务端-->发送消息完成", CommonConstants.LOG_PREFIX);
    }

}
